<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Learn2Lan Cryptography Study</title>

<style>
:root {
    --bg: #080b10;
    --panel: #111722;
    --panel2: #171e2b;
    --text: #f4f7fb;
    --muted: #98a2b3;

    --green: #8cff00;
    --purple: #b45cff;
    --orange: #ff9d00;
    --red: #ff4d67;

    --border: #283143;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    background:
        radial-gradient(circle at top left, rgba(180,92,255,.12), transparent 30%),
        radial-gradient(circle at top right, rgba(140,255,0,.08), transparent 25%),
        #080b10;
    color: var(--text);
    min-height: 100vh;
}

.wrapper {
    width: min(1000px, 94%);
    margin: auto;
    padding: 40px 0 60px;
}

/* HEADER */

header {
    margin-bottom: 28px;
}

.brand {
    color: var(--green);
    font-size: .9rem;
    font-weight: bold;
    letter-spacing: 3px;
    text-transform: uppercase;
}

h1 {
    margin: 8px 0 6px;
    font-size: clamp(2rem, 5vw, 3.5rem);
}

.subtitle {
    color: var(--muted);
    margin: 0;
}

/* STATS */

.stats {
    margin-top: 24px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}

.stat {
    background: rgba(17,23,34,.8);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 15px;
}

.stat-number {
    font-size: 1.5rem;
    font-weight: bold;
}

.stat-label {
    color: var(--muted);
    font-size: .8rem;
    margin-top: 4px;
}

.stat:nth-child(1) .stat-number {
    color: var(--purple);
}

.stat:nth-child(2) .stat-number {
    color: var(--green);
}

.stat:nth-child(3) .stat-number {
    color: var(--red);
}

.stat:nth-child(4) .stat-number {
    color: var(--orange);
}

/* PROGRESS */

.progress-track {
    height: 7px;
    background: #1c2330;
    border-radius: 10px;
    overflow: hidden;
    margin: 18px 0 26px;
}

.progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(
        90deg,
        var(--purple),
        var(--green),
        var(--orange)
    );
    transition: width .3s ease;
}

/* MODE BUTTONS */

.toolbar {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}

button {
    border: 1px solid var(--border);
    background: var(--panel);
    color: white;
    padding: 11px 16px;
    border-radius: 8px;
    cursor: pointer;
    font-weight: bold;
    transition: .2s;
}

button:hover {
    transform: translateY(-1px);
    border-color: var(--purple);
}

.active {
    border-color: var(--purple);
    box-shadow: 0 0 18px rgba(180,92,255,.2);
}

/* FLASHCARD */

.card-area {
    perspective: 1000px;
}

.flashcard {
    height: 340px;
    position: relative;
    cursor: pointer;
}

.card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform .55s;
    transform-style: preserve-3d;
}

.flashcard.flipped .card-inner {
    transform: rotateY(180deg);
}

.card-face {
    position: absolute;
    width: 100%;
    height: 100%;

    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;

    background:
        linear-gradient(
            145deg,
            rgba(180,92,255,.05),
            rgba(140,255,0,.02)
        ),
        var(--panel);

    border: 1px solid var(--border);
    border-radius: 20px;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    text-align: center;
    padding: 40px;
}

.card-front {
    box-shadow: 0 20px 60px rgba(0,0,0,.35);
}

.card-back {
    transform: rotateY(180deg);
    border-color: rgba(140,255,0,.35);
}

.card-label {
    position: absolute;
    top: 24px;
    left: 28px;

    text-transform: uppercase;
    letter-spacing: 2px;
    font-size: .72rem;
    color: var(--muted);
}

.card-front h2 {
    font-size: clamp(2.5rem, 8vw, 5rem);
    margin: 0;
    color: var(--purple);
}

.card-back h2 {
    font-size: clamp(1.5rem, 5vw, 2.5rem);
    max-width: 750px;
    color: var(--green);
    margin: 0;
}

.tap {
    position: absolute;
    bottom: 20px;
    color: var(--muted);
    font-size: .78rem;
}

/* RESULT BUTTONS */

.result-buttons {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 18px;
}

.know {
    border-color: rgba(140,255,0,.4);
}

.know:hover {
    background: rgba(140,255,0,.08);
    border-color: var(--green);
}

.missed {
    border-color: rgba(255,77,103,.4);
}

.missed:hover {
    background: rgba(255,77,103,.08);
    border-color: var(--red);
}

/* NAVIGATION */

.navigation {
    margin-top: 16px;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
}

.navigation button:last-child {
    justify-self: end;
}

.counter {
    color: var(--muted);
    font-size: .9rem;
}

.message {
    margin-top: 24px;
    padding: 18px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--panel);
    color: var(--muted);
    display: none;
}

/* MOBILE */

@media (max-width: 650px) {

    .stats {
        grid-template-columns: 1fr 1fr;
    }

    .flashcard {
        height: 300px;
    }

    .card-face {
        padding: 28px 20px;
    }

    .navigation {
        grid-template-columns: 1fr 1fr;
    }

    .counter {
        grid-column: 1 / -1;
        grid-row: 1;
        text-align: center;
    }

    .navigation button:last-child {
        justify-self: stretch;
    }

    .navigation button {
        width: 100%;
    }
}
</style>
</head>


<body>

<div class="wrapper">

<header>
    <div class="brand">Learn2Lan</div>

    <h1>Cryptography Study Lab</h1>

    <p class="subtitle">
        Algorithms, key sizes, block sizes, IVs, and message digests.
    </p>

    <div class="stats">

        <div class="stat">
            <div class="stat-number" id="totalCount">20</div>
            <div class="stat-label">Cards</div>
        </div>

        <div class="stat">
            <div class="stat-number" id="knownCount">0</div>
            <div class="stat-label">Known</div>
        </div>

        <div class="stat">
            <div class="stat-number" id="missedCount">0</div>
            <div class="stat-label">Missed</div>
        </div>

        <div class="stat">
            <div class="stat-number" id="remainingCount">20</div>
            <div class="stat-label">Unreviewed</div>
        </div>

    </div>

    <div class="progress-track">
        <div class="progress-bar" id="progressBar"></div>
    </div>
</header>


<div class="toolbar">

    <button id="allButton" class="active" onclick="showAll()">
        Study All
    </button>

    <button id="missedButton" onclick="showMissed()">
        Review Missed
    </button>

    <button onclick="shuffleCards()">
        Shuffle
    </button>

    <button onclick="resetProgress()">
        Reset Progress
    </button>

</div>


<div class="card-area">

    <div class="flashcard" id="flashcard" onclick="flipCard()">

        <div class="card-inner">

            <div class="card-face card-front">

                <span class="card-label">
                    Algorithm / Technology
                </span>

                <h2 id="cardFront"></h2>

                <span class="tap">
                    Click card to reveal answer
                </span>

            </div>


            <div class="card-face card-back">

                <span class="card-label">
                    Key Fact
                </span>

                <h2 id="cardBack"></h2>

                <span class="tap">
                    Click card to flip back
                </span>

            </div>

        </div>

    </div>

</div>


<div class="result-buttons">

    <button
        class="missed"
        onclick="event.stopPropagation(); markCard('missed')">

        ✕ Missed It

    </button>

    <button
        class="know"
        onclick="event.stopPropagation(); markCard('known')">

        ✓ Know It

    </button>

</div>


<div class="navigation">

    <button onclick="previousCard()">
        ← Previous
    </button>

    <div class="counter" id="counter"></div>

    <button onclick="nextCard()">
        Next →
    </button>

</div>


<div class="message" id="message"></div>

</div>



<script>

/*
=================================================
LEARN2LAN CRYPTOGRAPHY STUDY DATA
=================================================
*/

const cards = [

{
    front: "A5/1",
    back: "64-bit key; used with GSM cellular networks"
},

{
    front: "A5/3 / KASUMI",
    back: "128-bit key; associated with 3GPP"
},

{
    front: "WEP",
    back: "24-bit IV; uses RC4"
},

{
    front: "WPA / TKIP",
    back: "Uses RC4 with a 128-bit key"
},

{
    front: "WPA2",
    back: "48-bit IV"
},

{
    front: "AES",
    back: "128-bit blocks; 128-, 192-, or 256-bit keys"
},

{
    front: "DES",
    back: "64-bit block size"
},

{
    front: "3DES",
    back: "64-bit blocks; 112-bit key option"
},

{
    front: "IDEA",
    back: "64-bit blocks; 128-bit key"
},

{
    front: "Skipjack",
    back: "64-bit blocks; 80-bit key"
},

{
    front: "XTEA",
    back: "64-bit blocks; 128-bit key"
},

{
    front: "Blowfish",
    back: "Variable key size: 32–448 bits"
},

{
    front: "Twofish",
    back: "Variable key size up to 256 bits"
},

{
    front: "MD5",
    back: "Produces a 128-bit message digest"
},

{
    front: "SHA-1",
    back: "Produces a 160-bit message digest"
},

{
    front: "Trivium",
    back: "80-bit key + 80-bit IV"
},

{
    front: "Rabbit",
    back: "128-bit key + 64-bit IV"
},

{
    front: "PRESENT",
    back: "Hardware-oriented lightweight SPN block cipher"
},

{
    front: "SPECK",
    back: "Lightweight block cipher optimized for software"
},

{
    front: "SIMON",
    back: "Lightweight block cipher optimized for hardware"
}

];


/*
=================================================
APP STATE
=================================================
*/

let studyCards = [...cards];

let currentIndex = 0;

let progress =
    JSON.parse(
        localStorage.getItem("l2lCryptoProgress")
    ) || {};


/*
=================================================
DISPLAY CARD
=================================================
*/

function displayCard() {

    if (studyCards.length === 0) {

        document.getElementById("message").style.display = "block";

        document.getElementById("message").innerHTML =
            "No cards are currently in this study set.";

        document.getElementById("cardFront").innerText = "Complete";

        document.getElementById("cardBack").innerText =
            "Nothing to review.";

        document.getElementById("counter").innerText = "0 / 0";

        return;
    }

    document.getElementById("message").style.display = "none";

    if (currentIndex >= studyCards.length) {
        currentIndex = 0;
    }

    const card = studyCards[currentIndex];

    document.getElementById("cardFront").innerText =
        card.front;

    document.getElementById("cardBack").innerText =
        card.back;

    document.getElementById("counter").innerText =
        `${currentIndex + 1} / ${studyCards.length}`;

    document
        .getElementById("flashcard")
        .classList
        .remove("flipped");

    updateStats();
}


/*
=================================================
FLIP CARD
=================================================
*/

function flipCard() {

    document
        .getElementById("flashcard")
        .classList
        .toggle("flipped");

}


/*
=================================================
NAVIGATION
=================================================
*/

function nextCard() {

    if (studyCards.length === 0) return;

    currentIndex++;

    if (currentIndex >= studyCards.length) {
        currentIndex = 0;
    }

    displayCard();
}


function previousCard() {

    if (studyCards.length === 0) return;

    currentIndex--;

    if (currentIndex < 0) {
        currentIndex = studyCards.length - 1;
    }

    displayCard();
}


/*
=================================================
MARK CARD
=================================================
*/

function markCard(status) {

    if (studyCards.length === 0) return;

    const card =
        studyCards[currentIndex];

    progress[card.front] = status;

    localStorage.setItem(
        "l2lCryptoProgress",
        JSON.stringify(progress)
    );

    updateStats();

    setTimeout(
        nextCard,
        150
    );

}


/*
=================================================
STATS
=================================================
*/

function updateStats() {

    let known = 0;

    let missed = 0;

    cards.forEach(card => {

        if (progress[card.front] === "known") {
            known++;
        }

        if (progress[card.front] === "missed") {
            missed++;
        }

    });

    const reviewed =
        known + missed;

    const remaining =
        cards.length - reviewed;

    document.getElementById("totalCount").innerText =
        cards.length;

    document.getElementById("knownCount").innerText =
        known;

    document.getElementById("missedCount").innerText =
        missed;

    document.getElementById("remainingCount").innerText =
        remaining;

    const percent =
        cards.length
            ? (reviewed / cards.length) * 100
            : 0;

    document.getElementById("progressBar").style.width =
        percent + "%";

}


/*
=================================================
STUDY ALL
=================================================
*/

function showAll() {

    studyCards =
        [...cards];

    currentIndex = 0;

    document
        .getElementById("allButton")
        .classList
        .add("active");

    document
        .getElementById("missedButton")
        .classList
        .remove("active");

    displayCard();

}


/*
=================================================
REVIEW MISSED
=================================================
*/

function showMissed() {

    studyCards =
        cards.filter(
            card =>
                progress[card.front] === "missed"
        );

    currentIndex = 0;

    document
        .getElementById("missedButton")
        .classList
        .add("active");

    document
        .getElementById("allButton")
        .classList
        .remove("active");

    displayCard();

}


/*
=================================================
SHUFFLE
=================================================
*/

function shuffleCards() {

    for (
        let i = studyCards.length - 1;
        i > 0;
        i--
    ) {

        const j =
            Math.floor(
                Math.random() * (i + 1)
            );

        [
            studyCards[i],
            studyCards[j]
        ] =
        [
            studyCards[j],
            studyCards[i]
        ];

    }

    currentIndex = 0;

    displayCard();

}


/*
=================================================
RESET
=================================================
*/

function resetProgress() {

    const confirmed =
        confirm(
            "Reset all study progress?"
        );

    if (!confirmed) return;

    progress = {};

    localStorage.removeItem(
        "l2lCryptoProgress"
    );

    showAll();

}


/*
=================================================
KEYBOARD SHORTCUTS
=================================================
*/

document.addEventListener(
    "keydown",
    event => {

        if (event.code === "Space") {

            event.preventDefault();

            flipCard();

        }

        if (event.key === "ArrowRight") {
            nextCard();
        }

        if (event.key === "ArrowLeft") {
            previousCard();
        }

        if (event.key.toLowerCase() === "k") {
            markCard("known");
        }

        if (event.key.toLowerCase() === "m") {
            markCard("missed");
        }

    }
);


/*
=================================================
START APP
=================================================
*/

displayCard();

</script>

</body>
</html>
